package com.lmx.persistence.service;


import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.repoDomain.tmodel.BackVistInfo;
import com.lmx.repoDomain.tmodel.ConsultInfo;
import com.lmx.repoDomain.tmodel.Device;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.EmployeeLeaveFlow;
import com.lmx.repoDomain.tmodel.PersonLocation;
import com.lmx.repoDomain.tmodel.StaffAttendance;
import com.lmx.repoDomain.tmodel.StaffSchedule;
import com.lmx.repoDomain.tmodel.Tenant;
import com.lmx.repoDomain.tmodel.WorkDelivery;
import com.lmx.repoDomain.tmodel.WorkTimeSetting;
import com.lmx.repoDomain.tmodel.business.User;

/**
 * @author ytche
 * @param <T>
 */
@Service
@Scope("prototype")
public class EmployeeService<T> {
	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected CommonService commonService;	

	@Autowired
	private UserService<User> userSrv;
	
	@Autowired
	private DicttypeService dictService;
	
	@Autowired
	private CustomerService customerService;

	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	protected JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	/**
	 * 判断是否能够离职,在护工组的人员不能离职
	 *
	 * @author ytche
	 * @param oldData
	 * @param employee
	 * @return true可以离职 false 不能离职
	 * @date 2017年3月31日 下午3:28:30
	 */
	public boolean checkDimissionStatus(Employee oldData, Employee employee) {
		Boolean isLeaveChange = (oldData.getStaffStatus() != null && oldData
				.getStaffStatus().getTypecode()
				.equals(ICommonConstants.STAFFSTATUS.IN.lable()))
				&& (employee.getStaffStatus() != null && employee
						.getStaffStatus().getTypecode()
						.equals(ICommonConstants.STAFFSTATUS.LEAVE.lable()));
		if (isLeaveChange) {
			// 验证护理组
			String queryStr = "select e from EmployeeNursingGroup e where  e.employee = ?1 and e.delStatus != 1";
			List listGroup = new ArrayList<>();
			listGroup = this.em.createQuery(queryStr).setParameter(1, oldData)
					.getResultList();
			// 验证排班
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// 第几周
			Integer yearTab = now.getYear() + 1900;// 年
			Integer weekTab = CommonUtil.getWeek(now);// 周几
			queryStr = "select e from StaffSchedule e where e.delStatus != 1 and  e.employee.id = ?1  and ("
					+ "(e.year>?2) or (e.year=?2 and e.weekIndex>?3) or (e.year=?2 and e.weekIndex=?3 and e.week>=?4)"
					+ ")";
			List listDetail = new ArrayList<>();
			listDetail = this.em.createQuery(queryStr)
					.setParameter(1, oldData.getId())
					.setParameter(2, yearTab.toString())
					.setParameter(3, weekIndex.toString())
					.setParameter(4, weekTab.toString()).getResultList();
			int dataSize = listGroup.size() + listDetail.size();
			if (dataSize == 0) {
				return true;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}

	/**
	 * 删除用户
	 *
	 * @author ytche
	 * @param employee
	 * @date 2017年4月7日 上午10:18:50
	 */
	@Transactional
	public void delete(Employee employee) {
		dslJpaService.setEntityClass(Employee.class);
		dslJpaService.update(employee);
		userSrv.deleteByEmployee(employee);
		Device device = employee.getBracelet();
		if (device != null) {
			device.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1.label()));// 业务状态空闲
			device.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));// 绑定状态空闲
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(device);
		}

	}

	/**
	 * 复制 排班计划
	 */
	@Transactional
	public void copyStaffTimeSetting(String staffIds, int resourceWeekIndex,
			int targetWeekIndex) {
		Iterator it;
		int year = Integer.parseInt(CommonUtil.getCurrTime().substring(0, 4));
		String[] sIds = staffIds.split(",");
		List<Long> staffs = new ArrayList<>();
		for (String id : sIds) {
			staffs.add(Long.parseLong(id));
		}
		StringBuilder querySS = new StringBuilder(
				"select c from StaffSchedule c where c.delStatus!=1 and "
						+ " c.weekIndex=?1 and c.year=?2 and c.employee.id in (:staffs)");
		List<StaffSchedule> schedules = this.em.createQuery(querySS.toString())
				.setParameter(1, String.valueOf(resourceWeekIndex))
				.setParameter(2, String.valueOf(year))
				.setParameter("staffs", staffs).getResultList();
		if (schedules != null && schedules.size() > 0) {
			List dataList = new ArrayList<>();
			Employee staff = schedules.get(0).getEmployee();
			if (resourceWeekIndex >= targetWeekIndex) { // 跨年
				year++;
			}
			// 删除目标周数据
			StringBuilder query = new StringBuilder(
					"delete from StaffSchedule rp where rp.employee.id in (:staffs) and rp.year=?2 and rp.weekIndex=?3 ");
			this.em.createQuery(query.toString())
					.setParameter("staffs", staffs)
					.setParameter(2, String.valueOf(year))
					.setParameter(3, String.valueOf(targetWeekIndex))
					.executeUpdate();
			// copy
			for (StaffSchedule data : schedules) {
				if (data.getDelStatus() != null && data.getDelStatus() != 1) {
					StaffSchedule temp = new StaffSchedule();
					temp.setCreateDateTime(CommonUtil.getCurrTimes());
					temp.setDelStatus((short) 0);
					temp.setTenant(staff.getTenant());
					temp.setEmployee(data.getEmployee());
					temp.setWeek(data.getWeek());
					temp.setYear(String.valueOf(year));
					temp.setWeekIndex(String.valueOf(targetWeekIndex));
					temp.setWorkTimeSetting(data.getWorkTimeSetting());
					int sFlag = 0;
					if (targetWeekIndex > 9) {
						sFlag = 1;
					}
					StringBuilder sqlMonth = new StringBuilder();
					// 将年第几周 周几 转化为几号
					if (sFlag == 1) {
						sqlMonth.append("select day(STR_TO_DATE('" + year
								+ targetWeekIndex + " " + data.getWeek()
								+ "', '%X%V %w')) as day,"
								+ " month(STR_TO_DATE('" + year
								+ targetWeekIndex + " " + data.getWeek()
								+ "', '%X%V %w')) as month");
					} else {
						sqlMonth.append("select day(STR_TO_DATE('" + year + 0
								+ targetWeekIndex + " " + data.getWeek()
								+ "', '%X%V %w')) as day,"
								+ " month(STR_TO_DATE('" + year + 0
								+ targetWeekIndex + " " + data.getWeek()
								+ "', '%X%V %w')) as month");
					}

					List dataInSexCount = getJdbcTemplate().queryForList(
							sqlMonth.toString());
					it = dataInSexCount.iterator();
					while (it.hasNext()) {
						Map rece = (Map) it.next();
						temp.setMonth(rece.get("month").toString());
						temp.setDay(rece.get("day").toString());
					}
					dataList.add(temp);
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);
			}
		}
	}

	public Employee create(Employee employee) {
		if (employee.getBracelet() != null) {
			Device device = employee.getBracelet();
			device.setStatus(dictService.findByCode(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));
			device.setBindStatus(dictService.findByCode(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(device); 
		}
		dslJpaService.setEntityClass(Employee.class);
		return (Employee) dslJpaService.create(employee);
	}

	/**
	 * staff离职
	 */
	@Transactional
	public void leaveEmployee(Employee employee) {
		Device device = employee.getBracelet();
		if (device != null) {
			device.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1.label()));// 业务状态空闲
			device.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));// 绑定状态空闲
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(device);
		}
		userSrv.deleteByEmployee(employee);
		employee.setBracelet(null);
		dslJpaService.setEntityClass(Employee.class);
		dslJpaService.update(employee);
	}

	/**
	 * 判断是否能够离职,领导以及有设备不能离职
	 *
	 * @param employee
	 * @return true可以离职 false 不能离职
	 */
	public boolean checkLeaderAndDevice(Employee employee) {
		Employee oldData = userSrv.getEmployeeById(employee.getId());
		if (oldData.getLeaderFlag() != 1) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获取租户下的所有雇工
	 *
	 * @author ytche
	 * @param tenantId
	 * @return
	 * @date 2017年6月13日 下午5:11:56
	 */
	@SuppressWarnings("unchecked")
	public List<Employee> findByTenant(Long tenantId) {
		if (tenantId == null) {
			return null;
		}
		String hql = "from Employee where tenant.id= ?1 and delStatus= 0 and staffStatus.id=139 ";
		return this.em.createQuery(hql).setParameter(1, tenantId)
				.getResultList();
	}

	
	/**
	 * 获取当天有值班的Staff
	 *
	 * @author huibati
	 * @param tenantId
	 * @return
	 */
	public List<Employee> findByWorkTimeSettingOnDay(Long tenantId, Long dateTime) {
		if (tenantId == null) {
			return null;
		}
		List<Employee> staffs = new ArrayList<>();
		Date now = new Date(dateTime * 1000);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);
		int hour = now.getHours();
		int min = now.getMinutes();
        //昨天的年周以及周几
		Integer proWeekIndex = weekIndex;
		Integer proYearTab = yearTab;
		Integer proWeekTab = weekTab - 1;
		if (proWeekTab == -1) {
			proWeekTab = 6;
			proWeekIndex -= 1;
			if (proWeekIndex == 0) {
				proWeekIndex = 52;
				proYearTab -= 1;
			}
		}
		// 当天有排班的所有员工
		String hql = "select c.employee from StaffSchedule c where c.tenant.id= ?1 and c.delStatus= 0 and ("
				+ "( c.year=?2 and c.weekIndex=?3 and c.week=?4 ) "
				+ "or "
				+ "( c.year=?5 and c.weekIndex=?6 and c.week=?7 and c.workTimeSetting.ktFlag=1 ) "
				+ ")";
		List<Employee> dataList = this.em.createQuery(hql)
				.setParameter(1, tenantId).setParameter(2, yearTab.toString())
				.setParameter(3, weekIndex.toString())
				.setParameter(4, weekTab.toString()).setParameter(5, proYearTab.toString())
				.setParameter(6, proWeekIndex.toString())
				.setParameter(7, proWeekTab.toString()).getResultList();
		return dataList;
	}
	
	
	/**
	 * 获取当前时间值班Staff
	 *
	 * @author huibati
	 * @param tenantId
	 * @return
	 */
	public List<Employee> findByWorkTimeSettingOnTime(Long tenantId, Long dateTime) {
		if (tenantId == null) {
			return null;
		}
		List<Employee> staffs = new ArrayList<>();
		Date now = new Date(dateTime * 1000);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);
		int hour = now.getHours();
		int min = now.getMinutes();
        //昨天的年周以及周几
		Integer proWeekIndex = weekIndex;
		Integer proYearTab = yearTab;
		Integer proWeekTab = weekTab - 1;
		if (proWeekTab == -1) {
			proWeekTab = 6;
			proWeekIndex -= 1;
			if (proWeekIndex == 0) {
				proWeekIndex = 52;
				proYearTab -= 1;
			}
		}
		
		double date = hour + min / 60.0;
		// 当天有排班的所有员工
		String hql = "select c from StaffSchedule c where c.tenant.id= ?1 and c.delStatus= 0 and ("
				+ "( c.year=?2 and c.weekIndex=?3 and c.week=?4 ) "
				+ "or "
				+ "( c.year=?5 and c.weekIndex=?6 and c.week=?7 and c.workTimeSetting.ktFlag=1 ) "
				+ ")";
		List<StaffSchedule> dataList = this.em.createQuery(hql)
				.setParameter(1, tenantId).setParameter(2, yearTab.toString())
				.setParameter(3, weekIndex.toString())
				.setParameter(4, weekTab.toString()).setParameter(5, proYearTab.toString())
				.setParameter(6, proWeekIndex.toString())
				.setParameter(7, proWeekTab.toString()).getResultList();
		for (StaffSchedule ss : dataList) {
			if (ss != null && ss.getWorkTimeSetting() != null
					&& ss.getWorkTimeSetting().getStartTime() != null
					&& ss.getWorkTimeSetting().getEndTime() != null) {
				int hourStart = Integer.parseInt(ss.getWorkTimeSetting()
						.getStartTime().split(":")[0]);
				int minStart = Integer.parseInt(ss.getWorkTimeSetting()
						.getStartTime().split(":")[1]);
				double dateStart = hourStart + minStart / 60.0;
				int hourEnd = Integer.parseInt(ss.getWorkTimeSetting()
						.getEndTime().split(":")[0]);
				int minEnd = Integer.parseInt(ss.getWorkTimeSetting()
						.getEndTime().split(":")[1]);
				if (hourEnd == 0) {
					hourEnd = 24;
				}
				double dateEnd = hourEnd + minEnd / 60.0;
				// 排班未跨天
				if (dateStart < dateEnd) {
					if (dateStart <= date && date <= dateEnd) {
						if(staffs.contains(ss.getEmployee())){
							
						}else{
							staffs.add(ss.getEmployee());
						}
					}
				}
				// 排班跨天
				if (dateStart >= dateEnd) {
					if ((dateStart <= date && date <= 24.0) || date <= dateEnd) {
						if(staffs.contains(ss.getEmployee())){
							
						}else{
							staffs.add(ss.getEmployee());
						}
					}
				}
			}
		}
		return staffs;
	}

	/**
	 * 判断班次是否跨天
	 * 1跨天0未跨天
	 * @author huibati
	 * @param 2017年10月19日
	 */
	public int WorkTimeSettingKTFlag(WorkTimeSetting setting) {
		int hourStart = Integer.parseInt(setting.getStartTime().split(":")[0]);
		int minStart = Integer.parseInt(setting.getStartTime().split(":")[1]);
		double dateStart = hourStart + minStart / 60.0;
		int hourEnd = Integer.parseInt(setting.getEndTime().split(":")[0]);
		int minEnd = Integer.parseInt(setting.getEndTime().split(":")[1]);
		if (hourEnd == 0) {
			hourEnd = 24;
		}
		double dateEnd = hourEnd + minEnd / 60.0;
		// 排班未跨天
		if (dateStart < dateEnd) {
			return 0;
		}
		// 排班跨天
		if (dateStart >= dateEnd) {
			return 1;
		}
		return -1;
	}
	
	/**
	 * @author huibati
	 * @param  昨天员工位置信息
	 * 根据昨天员工位置信息产生前天以及昨天考勤数据
	 *            2017年8月1日
	 */
	@Transactional
	public void createWorkTimeByLocation(List<PersonLocation> slList) {
		Integer beYesTime = 0;
		Integer yesTime = 0;
		Integer yesTimeEnd = 0;
		//考勤更新列表
		List updateList = new ArrayList<>();
		//考勤新增列表
		List insertList = new ArrayList<>();
		try {
			beYesTime = CommonUtil
					.strToIntegerTime(CommonUtil.getBeforeYesterdayCurrTimeForString().substring(0, 10) + " 00:00:00");
			yesTime = CommonUtil
					.strToIntegerTime(CommonUtil.getYesterdayCurrTimeForString().substring(0, 10) + " 00:00:00");
			yesTimeEnd = CommonUtil
					.strToIntegerTime(CommonUtil.getYesterdayCurrTimeForString().substring(0, 10) + " 23:59:59");
		} catch (Exception e) {
			logger.error("pase date error:" + e);
		}
		// 前天相关时间数据
		Date beYes = new Date(beYesTime * 1000l);
		int yearBeYes = (beYes.getYear() + 1900);
		int weekIndexBeYes = CommonUtil.getWeekIndexFromSun(beYes);
		int weekTabBeYes = CommonUtil.getWeek(beYes);
		// 昨天相关时间数据
		Date yes = new Date(yesTime * 1000l);
		int yearYes = (yes.getYear() + 1900);
		int weekIndexYes = CommonUtil.getWeekIndexFromSun(yes);
		int weekTabYes = CommonUtil.getWeek(yes);
		//昨天请假数据 key:staffid-周几
		Map<String, Tenant> leaveMap = new HashMap<>();
		//考勤数据 key:staffid-settingid-考勤时间
		Map<String, StaffAttendance> dataMap = new HashMap<>();
		//员工两天排班 key:staffid-周几
		Map<String, List<WorkTimeSetting>> settingMap = new HashMap<>();
		// 获取前天以及昨天的排班
		StringBuilder queryWorkTime = new StringBuilder(
				" select c from StaffSchedule c where c.delStatus!=1 and c.workTimeSetting.startTime is not null and c.workTimeSetting.endTime is not null  and ("
						+ " ( c.year=?2 and c.weekIndex=?3 and c.week=?4 ) " + " or "
						+ " ( c.year=?5 and c.weekIndex=?6 and c.week=?7 )" + " ) ");
		List<StaffSchedule> ssList = this.em.createQuery(queryWorkTime.toString())
				.setParameter(2, String.valueOf(yearBeYes)).setParameter(3, String.valueOf(weekIndexBeYes))
				.setParameter(4, String.valueOf(weekTabBeYes)).setParameter(5, String.valueOf(yearYes))
				.setParameter(6, String.valueOf(weekIndexYes)).setParameter(7, String.valueOf(weekTabYes))
				.getResultList();
		if (ssList != null) {
			for (StaffSchedule ss : ssList) {
				if (!settingMap.containsKey(ss.getEmployee().getId() + "-" + ss.getWeek())) {
					List tempSetting = new ArrayList<>();
					tempSetting.add(ss.getWorkTimeSetting());
					settingMap.put(ss.getEmployee().getId() + "-" + ss.getWeek(), tempSetting);
				} else {
					if (!settingMap.get(ss.getEmployee().getId() + "-" + ss.getWeek())
							.contains(ss.getWorkTimeSetting())) {
						settingMap.get(ss.getEmployee().getId() + "-" + ss.getWeek()).add(ss.getWorkTimeSetting());
					}
				}
			}
		}
		// 获取前天以及昨天的考勤
		StringBuilder queryAttendance = new StringBuilder(" select c from StaffAttendance c where c.delStatus!=1  and "
				+ " ( c.attendanceTime=?2 or c.attendanceTime=?3 )");
		List<StaffAttendance> saList = this.em.createQuery(queryAttendance.toString()).setParameter(2, beYesTime)
				.setParameter(3, yesTime).getResultList();
		if (saList != null) {
			for (StaffAttendance sa : saList) {
				dataMap.put(
						sa.getEmployee().getId() + "-" + sa.getWorkTimeSetting().getId() + "-" + sa.getAttendanceTime(),
						sa);
			}
		}
		//获取昨天请假情况
		Map<String, String> leaveFilter=new HashMap<>();
		leaveFilter.put("startTime", yesTime.toString());
		leaveFilter.put("endTime", yesTimeEnd.toString());
		List<EmployeeLeaveFlow> leaveData=this.findEmployeeInLeave(leaveFilter);
		if (leaveData != null && leaveData.size() > 0) {
			for (EmployeeLeaveFlow data : leaveData) {
				leaveMap.put(data.getApplicant().getId() + "-" + weekTabYes, data.getTenant());
			}
		}
		//遍历位置信息
		for (PersonLocation pl : slList) {
			if (pl != null && pl.getEmployee() != null) {
				// 考勤开始以及结束时间
				Integer beYesEndTime = 0;
				Integer yesStartTime = 0;
				Integer yesEndTime = 0;
				List<WorkTimeSetting> beYesSettingList = new ArrayList<>();// 前天排班
				List<WorkTimeSetting> yesSettingList = new ArrayList<>();// 昨天排班
				if (settingMap.containsKey(pl.getEmployee().getId() + "-" + weekTabBeYes)) {
					beYesSettingList = settingMap.get(pl.getEmployee().getId() + "-" + weekTabBeYes);
				}
				if (settingMap.containsKey(pl.getEmployee().getId() + "-" + weekTabYes)) {
					yesSettingList = settingMap.get(pl.getEmployee().getId() + "-" + weekTabYes);
				}
				// 前天的排班若跨天则需验证是否需要设置下班时间考勤
				for (WorkTimeSetting beYesSetting : beYesSettingList) {
					StaffAttendance beYesAttendance = null;// 前天考勤
					if (dataMap.containsKey(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime)) {
						beYesAttendance = dataMap
								.get(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime);
					}
					if (beYesSetting != null && checkWorkTimeDay(beYesSetting) == 1) {
						try {
							beYesEndTime = CommonUtil
									.strToIntegerTime(CommonUtil.getYesterdayCurrTimeForString().substring(0, 10) + " "
											+ beYesSetting.getEndTime() + ":00");
						} catch (ParseException e) {
							logger.error("pase error " + e);
						}
						if (beYesAttendance == null) {
							//前天考勤数据为空
							beYesAttendance = new StaffAttendance();
							beYesAttendance.setEmployee(pl.getEmployee());
							beYesAttendance.setDelStatus((short) 0);
							beYesAttendance.setTenant(pl.getEmployee().getTenant());
							beYesAttendance.setCreateDateTime(CommonUtil.getCurrTimes());
							beYesAttendance.setEndWorkTime(pl.getLocationTime());
							beYesAttendance.setEndWorkPoint(pl.getRoom());
							beYesAttendance.setAttendanceTime(beYesTime);
							beYesAttendance.setWorkTimeSetting(beYesSetting);
							beYesAttendance.setStartTime(beYesSetting.getStartTime());
							beYesAttendance.setEndTime(beYesSetting.getEndTime());
							dataMap.put(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime,
									beYesAttendance);
						} else {
							// 前天考勤下班考勤时间为空
							if (beYesAttendance.getEndWorkTime() == null ) {
								beYesAttendance.setEndWorkTime(pl.getLocationTime());
								beYesAttendance.setEndWorkPoint(pl.getRoom());
								beYesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
								dataMap.put(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime,
										beYesAttendance);
							}else{
								//班次结束时间<=位置时间<=当前已存下班考勤时间
								if (beYesEndTime <= beYesAttendance.getEndWorkTime()
										&& beYesEndTime <= pl.getLocationTime()
										&& pl.getLocationTime() <= beYesAttendance.getEndWorkTime()) {
									beYesAttendance.setEndWorkTime(pl.getLocationTime());
									beYesAttendance.setEndWorkPoint(pl.getRoom());
									beYesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
									dataMap.put(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime,
											beYesAttendance);
								}
								//班次结束时间>当前已存下班考勤时间    且   位置时间>当前已存下班考勤时间
								if (beYesEndTime > beYesAttendance.getEndWorkTime()
										&& pl.getLocationTime() > beYesAttendance.getEndWorkTime()) {
									beYesAttendance.setEndWorkTime(pl.getLocationTime());
									beYesAttendance.setEndWorkPoint(pl.getRoom());
									beYesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
									dataMap.put(pl.getEmployee().getId() + "-" + beYesSetting.getId() + "-" + beYesTime,
											beYesAttendance);
								}
							}	
						}
					} // end if beyesseting
				}
				// 昨天排班时间若跨天则只需验证是否设置上班时间考勤否则还需验证设置下班时间考勤
				for (WorkTimeSetting yesSetting : yesSettingList) {
					StaffAttendance yesAttendance = null;// 昨天考勤
					if (dataMap.containsKey(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime)) {
						yesAttendance = dataMap
								.get(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime);
					}
					if (yesSetting != null) {
						try {
							yesEndTime = CommonUtil
									.strToIntegerTime(CommonUtil.getYesterdayCurrTimeForString().substring(0, 10) + " "
											+ yesSetting.getEndTime() + ":00");
							yesStartTime = CommonUtil
									.strToIntegerTime(CommonUtil.getYesterdayCurrTimeForString().substring(0, 10) + " "
											+ yesSetting.getStartTime() + ":00");
						} catch (ParseException e) {
							logger.error("pase error " + e);
						}
						// 设置昨天上班考勤时间
						if (yesAttendance == null) {
							//昨天考勤数据为空
							yesAttendance = new StaffAttendance();
							yesAttendance.setEmployee(pl.getEmployee());
							yesAttendance.setDelStatus((short) 0);
							yesAttendance.setTenant(pl.getEmployee().getTenant());
							yesAttendance.setCreateDateTime(CommonUtil.getCurrTimes());
							yesAttendance.setStartWorkTime(pl.getLocationTime());
							yesAttendance.setStartWorkPoint(pl.getRoom());
							yesAttendance.setAttendanceTime(yesTime);
							yesAttendance.setWorkTimeSetting(yesSetting);
							yesAttendance.setStartTime(yesSetting.getStartTime());
							yesAttendance.setEndTime(yesSetting.getEndTime());
							dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
									yesAttendance);
						} else {
							// 昨天考勤上班考勤时间为空
							if (yesAttendance.getStartWorkTime() == null) {
								yesAttendance.setStartWorkTime(pl.getLocationTime());
								yesAttendance.setStartWorkPoint(pl.getRoom());
								yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
								dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
										yesAttendance);
							}else{
								//班次开始时间<当前已存上班考勤时间  且   位置时间<当前已存上班考勤时间
								if (yesStartTime < yesAttendance.getStartWorkTime()
										&& pl.getLocationTime() < yesAttendance.getStartWorkTime()) {
									yesAttendance.setStartWorkTime(pl.getLocationTime());
									yesAttendance.setStartWorkPoint(pl.getRoom());
									yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
									dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
											yesAttendance);
								}
								//班次开始时间>=位置时间>=当前已存上班考勤时间
								if (yesStartTime >= yesAttendance.getStartWorkTime()
										&& yesStartTime >= pl.getLocationTime()
										&& pl.getLocationTime() >= yesAttendance.getStartWorkTime()) {
									yesAttendance.setStartWorkTime(pl.getLocationTime());
									yesAttendance.setStartWorkPoint(pl.getRoom());
									yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
									dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
											yesAttendance);
								}
							}
						}
						// 昨天未跨天验证设置下班签到
						if (checkWorkTimeDay(yesSetting) == 0) {
							if (yesAttendance == null) {
								//昨天考勤数据为空
								yesAttendance = new StaffAttendance();
								yesAttendance.setEmployee(pl.getEmployee());
								yesAttendance.setDelStatus((short) 0);
								yesAttendance.setTenant(pl.getEmployee().getTenant());
								yesAttendance.setCreateDateTime(CommonUtil.getCurrTimes());
								yesAttendance.setEndWorkTime(pl.getLocationTime());
								yesAttendance.setEndWorkPoint(pl.getRoom());
								yesAttendance.setAttendanceTime(yesTime);
								yesAttendance.setWorkTimeSetting(yesSetting);
								yesAttendance.setStartTime(yesSetting.getStartTime());
								yesAttendance.setEndTime(yesSetting.getEndTime());
								dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
										yesAttendance);
							} else {
								// 昨天考勤下班考勤时间为空
								if (yesAttendance.getEndWorkTime() == null ) {
									yesAttendance.setEndWorkTime(pl.getLocationTime());
									yesAttendance.setEndWorkPoint(pl.getRoom());
									yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
									dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
											yesAttendance);
								}else{
									//班次结束时间<=位置时间<=当前已存下班考勤时间
									if (yesEndTime <= yesAttendance.getEndWorkTime()
											&& beYesEndTime <= pl.getLocationTime()
											&& pl.getLocationTime() <= yesAttendance.getEndWorkTime()) {
										yesAttendance.setEndWorkTime(pl.getLocationTime());
										yesAttendance.setEndWorkPoint(pl.getRoom());
										yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
										dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
												yesAttendance);
									}
									//班次结束时间>当前已存下班考勤时间    且   位置时间>当前已存下班考勤时间
									if (yesEndTime > yesAttendance.getEndWorkTime()
											&& pl.getLocationTime() > yesAttendance.getEndWorkTime()) {
										yesAttendance.setEndWorkTime(pl.getLocationTime());
										yesAttendance.setEndWorkPoint(pl.getRoom());
										yesAttendance.setLastUpdateDateTime(CommonUtil.getCurrTimes());
										dataMap.put(pl.getEmployee().getId() + "-" + yesSetting.getId() + "-" + yesTime,
												yesAttendance);
									}
								}
							}
						}
					} // end if yesseting
				}
			} // end if pl
		} // end for pl
		
		//根据请假信息以及排班产生相应请假考勤
		Iterator iter = leaveMap.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			String key =  (String) entry.getKey();
			if(settingMap.containsKey(key)){
				Long staffId=Long.parseLong(key.split("-")[0]);
				Employee staff=new Employee();
				staff.setId(staffId);
				List<WorkTimeSetting> settings=settingMap.get(key);
				if(settings!=null){
					for(WorkTimeSetting setting:settings){
						StaffAttendance yesAttendance = new StaffAttendance();
						yesAttendance.setEmployee(staff);
						yesAttendance.setDelStatus((short) 0);
						yesAttendance.setTenant(leaveMap.get(key));
						yesAttendance.setCreateDateTime(CommonUtil.getCurrTimes());
						yesAttendance.setAttendanceTime(yesTime);
						yesAttendance.setWorkTimeSetting(setting);
						yesAttendance.setStartTime(setting.getStartTime());
						yesAttendance.setEndTime(setting.getEndTime());
						yesAttendance.setRemark("leave");
						insertList.add(yesAttendance);
					}
				}
			}
		}
		
		//遍历map进行更新以及增添操作
		iter = dataMap.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			StaffAttendance val = (StaffAttendance) entry.getValue();
			if (val.getId() == null) {
				insertList.add(val);
			} else {
				updateList.add(val);
			}
		}
		commonService.batchInsert(insertList);
		commonService.batchUpdate(updateList);
	}

	/**
	 *   @author huibati
	 *   @param
	 *   验证排班是否跨天
	 *   2017年8月1日 
	 */
	public int checkWorkTimeDay(WorkTimeSetting wts) {
		if (wts != null && wts != null && wts != null) {
			int hourStart = Integer.parseInt(wts.getStartTime().split(":")[0]);
			int minStart = Integer.parseInt(wts.getStartTime().split(":")[1]);
			double dateStart = hourStart + minStart / 60.0;
			int hourEnd = Integer.parseInt(wts.getEndTime().split(":")[0]);
			int minEnd = Integer.parseInt(wts.getEndTime().split(":")[1]);
			if (hourEnd == 0) {
				hourEnd = 24;
			}
			double dateEnd = hourEnd + minEnd / 60.0;
			// 排班未跨天
			if (dateStart < dateEnd) {
				return 0;
			}
			// 排班跨天
			return 1;
		}
		return -1;
	}
	
	/**
	 * 获取某个时间段内员工的请假状况
	 *
	 * @author huibati
	 * @return
	 * @date 2017年8月3日 上午11:04:58
	 */
	private List<EmployeeLeaveFlow> findEmployeeInLeave(
			Map<String, String> filter) {
		String startTimeStr = filter.get("startTime");
		String endTimeStr = filter.get("endTime");
		Integer startTime = null;
		Integer endTime = null;
		String queryHql = "from EmployeeLeaveFlow as e where e.delStatus=0 and (e.flowStatus=1 or  e.flowStatus=99) and e.applicant is not null ";
		if (StringUtils.isNotBlank(startTimeStr)) {
			startTime = new Integer(startTimeStr);
			queryHql += " and (realEndTime >= :startTime or realEndTime is null ) ";
		}
		if (StringUtils.isNotBlank(endTimeStr)) {
			endTime = new Integer(endTimeStr);
			queryHql += " and expectStartTime <= :endTime ";
		}
		Query query = this.em.createQuery(queryHql);
		if (StringUtils.isNotBlank(startTimeStr)) {
			query.setParameter("startTime", startTime);
		}
		if (StringUtils.isNotBlank(endTimeStr)) {
			query.setParameter("endTime", endTime);
		}
		return query.getResultList();
	}
	
	
	/**
	 * 获取交接班数据
	 */
	public WorkDelivery getWorkDelivery(WorkDelivery WorkDelivery) {
		StringBuilder query = new StringBuilder(
				"select c from WorkDelivery c where c.id= ?1");
		Long id = WorkDelivery.getId();
		WorkDelivery ct = (WorkDelivery) this.em.createQuery(query.toString())
				.setParameter(1, id).getSingleResult();
		return ct;
	}
	
	
	/**
	 * 删除数据为空的交接班
	 */
	@Transactional
	public void deleteNullWorkDelivery() {
	
		StringBuilder query = new StringBuilder(
				"delete from WorkDelivery rp where rp.receiver is null and ( rp.remark is null or rp.remark = '') ");
		this.em.createQuery(query.toString())
				.executeUpdate();
	}

	
	/**
	 * 删除数据为空的回访数据
	 */
	@Transactional
	public void deleteNullBackvist() {
		StringBuilder query = new StringBuilder(
				"delete from BackVistInfo rp where rp.accessType is null and ( rp.remark is null or rp.remark = '' ) and rp.liveIntent is null and rp.vistUser is null and ( rp.customerName is null or rp.customerName = '' )and ( rp.customerTel is null or rp.customerTel = '' )") ;
		this.em.createQuery(query.toString())
				.executeUpdate();
	}
	
	
	/**
	 * 获取咨询信息相应的回访数量
	 *
	 * @author huibati
	 * @return
	 */
	public List<ConsultInfo> getBackvistNumByConsult(List<ConsultInfo> data) {
		if (data != null && data.size() > 0) {
			Map<Long, Integer> dataIndex = new HashMap<>();
			for (int i = 0; i < data.size(); i++) {
				data.get(i).setBackvistNum(0);
				dataIndex.put(data.get(i).getId(), i);
			}
			StringBuilder sql = new StringBuilder(
					" select c from BackVistInfo c where c.delStatus!=1  and tenant.id=?1 ");
			List<BackVistInfo> saList = this.em.createQuery(sql.toString())
					.setParameter(1, ActionContextHolder.getContext().getTenantId()).getResultList();
			for (BackVistInfo back : saList) {
				if (back.getConsultInfo() != null && dataIndex.containsKey(back.getConsultInfo().getId())) {
					int backvistNum = data.get(dataIndex.get(back.getConsultInfo().getId())).getBackvistNum();
					data.get(dataIndex.get(back.getConsultInfo().getId())).setBackvistNum(backvistNum + 1);
				}
			}
		}
		return data;
	}
	
	/**
	 *   新建交接班并设置已入住人数、请假/退住老人、新入住老人
	 *   @author huibati
	 *   @param
	 *   2017年9月11日
	 */
	public WorkDelivery createWorkDelivery(WorkDelivery data) {
//		// 处于试住入住
//		List customerInList = customerService.getCustomerInOrTry(ActionContextHolder.getContext().getTenantId());
//		int inBedNum = customerInList == null || customerInList.size() == 0 ? 0 : customerInList.size();
//		data.setInBedNum(inBedNum + "");
//		// 退住以及请假
//		List<Customer> customerOutList = customerService.getCustomerOutOrLeaving(ActionContextHolder.getContext().getTenantId(),CommonUtil.getCurrTimes());
//		String outOldPerson = "无";
//		if(customerOutList != null && customerOutList.size() != 0){
//			outOldPerson = "";
//			for(Customer customer:customerOutList){
//				outOldPerson+=customer.getName()+",";
//			}
//			outOldPerson=outOldPerson.substring(0, outOldPerson.length()-1);
//		}
//		data.setOutOldPerson(outOldPerson);
//		// 当天入住老人
//		List<Customer>  customerNewInList = customerService.getCustomerNewIn(ActionContextHolder.getContext().getTenantId(),CommonUtil.getCurrTimes());
//		String newInOldPerson = "无";
//		if(customerNewInList != null && customerNewInList.size() != 0){
//			newInOldPerson = "";
//			for(Customer customer:customerNewInList){
//				newInOldPerson+=customer.getName()+",";
//			}
//			newInOldPerson=newInOldPerson.substring(0, newInOldPerson.length()-1);
//		}
//		data.setNewInOldPerson(newInOldPerson);
		dslJpaService.setEntityClass(WorkDelivery.class);
		dslJpaService.create(data);
		return data;
	}
	
	
	/**
	 * 新建/修改BackVistInfo 将咨询意向同步至咨询数据
	 *
	 * @author huibati
	 * @return
	 */
	@Transactional
	public BackVistInfo operateBackVistInfo(BackVistInfo data) {
		if (data.getId() != null) {
			dslJpaService.setEntityClass(BackVistInfo.class);
			dslJpaService.update(data);
		} else {
			dslJpaService.setEntityClass(BackVistInfo.class);
			dslJpaService.create(data);
		}
		if (data.getConsultInfo() != null && data.getLiveIntent() != null) {
			String queryCon = "update ConsultInfo u set u.liveIntent = ?1 , u.lastUpdateDateTime = ?2 where u.id = ?3";
			this.em.createQuery(queryCon).setParameter(1, data.getLiveIntent())
					.setParameter(2, CommonUtil.getCurrTimes()).setParameter(3, data.getConsultInfo().getId())
					.executeUpdate();
		}
		return data;
	}
	
	
	/**
	 * 获取user对应employee
	 *
	 * @author huibati
	 * @return
	 */
	public Employee getEmployeeByUser(User data) {
		if (data != null) {
			StringBuilder sql = new StringBuilder(" select c.employee from User c where c.delStatus!=1  and c.id=?1 ");
			List<Employee> saList = this.em.createQuery(sql.toString()).setParameter(1, data.getId()).getResultList();
			return saList == null || saList.size() < 1 ? null : saList.get(0);
		}
		return null;
	}
	
	
	/**
	 *   获取user所对应的全部tenant
	 *   @author huibati
	 *   @param
	 *   2017年10月26日
	 */
	public List<Tenant> getTenantsByUser(User user) {
		List<Tenant> tenants = new ArrayList<>();
		List<User> users = new ArrayList<>();
		user=(User) this.em.createQuery("select c from User c where c.id = ?1").setParameter(1, user.getId()).getSingleResult();
		String queryTenant = "select c.tenant from User c where c.delStatus != 1 and c.loginName = ?2 and c.passcode = ?3 ";
		tenants= this.em.createQuery(queryTenant).setParameter(2, user.getLoginName()).setParameter(3, user.getPasscode()).getResultList();
		return tenants;
	}
	
}
